package com.huawei.experiencereuse.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class ImageProcessor {
    public static float[] processImageToFloatArrayForVit(String path) {
        Bitmap bitmap = loadAndResizeBitmap(path, 224, 224);
        float[] floatArray = convertBitmapToFloatArray(bitmap);

//        System.out.printf("floatArray(%d): %f, %f, %f ... %f, %f, %f \n", floatArray.length, floatArray[0], floatArray[1], floatArray[2], floatArray[221], floatArray[222], floatArray[223]);
//        System.out.printf("floatArray(%d): %f, %f, %f ... %f, %f, %f \n", floatArray.length, floatArray[224*224+0], floatArray[224*224+1], floatArray[224*224+2], floatArray[224*224+221], floatArray[224*224+222], floatArray[224*224+223]);
//        System.out.printf("floatArray(%d): %f, %f, %f, \n", floatArray.length, floatArray[floatArray.length - 3], floatArray[floatArray.length - 2], floatArray[floatArray.length - 1]);

        // chenfuduo memory leak here
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
        }

        return floatArray;
    }

    private static Bitmap loadAndResizeBitmap(String path, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);

        options.inSampleSize = calculateInSampleSize(options, width, height);
        options.inJustDecodeBounds = false;
        // options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;

        Bitmap bitmap = BitmapFactory.decodeFile(path, options);
        return Bitmap.createScaledBitmap(bitmap, width, height, true);
    }

    private static int calculateInSampleSize(
            BitmapFactory.Options options,
            int reqWidth,
            int reqHeight
    ) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    private static float[] convertBitmapToFloatArray(Bitmap bitmap) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int numPixels = width * height;
        int numValues = numPixels * 3;

        float[] floatArray = new float[numValues];

        int iB = 0;
        int iG = 0;
        int iR = 0;

        for(int i = 0; i < height; ++i) {
            for(int j = 0; j < width; ++j) {
                iR = i * width + j;
                iG  = iR + (width * height);
                iB = iG + (width * height);

                int color = bitmap.getPixel(j, i);
                int r = (color >> 16) & 0xFF;
                int g = (color >> 8) & 0xFF;
                int b = color & 0xFF;

                float rNorm = (r / 255.0f -  0.48145466f) * (1 / 0.26862954f);
                float gNorm = (g / 255.0f -0.4578275f) * (1 / 0.26130258f);
                float bNorm = (b / 255.0f - 0.40821073f) * (1 / 0.27577711f);

                floatArray[iR] = rNorm;
                floatArray[iG] = gNorm;
                floatArray[iB] = bNorm;
            }
        }

        return  floatArray;
    }
}
